<template>
  <div>
    ts的类型断言等
    <a id="link" href="http://www.baidu.com">标签</a>
  </div>
</template>

<script  setup lang="ts">
import {onMounted,ref} from 'vue'
  // 1 类型断言 
// 有时候你会比 TS 更加明确一个值的类型，此时，可以使用类型断言来指定更具体的类型。 比如，

// aLink 的类型 HTMLElement，该类型只包含所有标签公共的属性或方法
// 这个类型太宽泛，没包含 a 元素特有的属性或方法，如 href
// 但是我们明确知道获取的是一个 `A` 元素，可以通过 `类型断言` 给它指定一个更具体的类型。

// 类型断言语法     变量 as 类型
// 类型断言语法2    <类型>变量
// HTMLElement-- html标签的类型
// const aLink:HTMLElement = document.getElementById('link') 
onMounted(()=>{
  // HTMLAnchorElement 对A标签的标注
    const aLink = document.getElementById('link') as HTMLAnchorElement
    console.log(aLink.href,"------")
  // 如div HTMLDivElement
    function say(x:number){
      // x as string 类型断言 x为string
      console.log((x as string).length)
      // 类型断言的写法2 
       console.log((<string>x).length)
    }
    say("adsfgesf")
})

// 2. ts的class类 
// public：	共有，可以在任何地方被访问（默认）
// protected：	受保护，可以被其自身以及其子类访问
// private：	私有，只能被其定义所在的类访问
class Car{
    public name:string;
    protected color:string;
  constructor(name:string,color:string){
      this.name=name;
      this.color=color;
  }
  public run(km:number):void{
    console.log("本次行驶了"+km)
  }
  protected fly(){ // protected 可以在自身访问 和子类访问 
                  // 实例化对象不能访问
    console.log("飞")
  }
  private eat(){//只能被其定义所在的类访问

    console.log("吃")
  }
  static jia(){ //静态方法

  }
}
let benchi=new Car("奔驰迈巴赫","234234")
benchi.run(18888)
// benchi.fly()
// benchi.eat()


// - 在TypeScript中，泛型是一种创建**可复用**代码组件的工具。这种组件不只能被一种类型使用，而是能被多种类型复用。类似于参数的作用，泛型是一种用以增强类型（types）、接口（interfaces）、函数类型等**能力的非常可靠的手段。  
// 接口的应用
interface ICar{
  name:string,
  age:string
}
function say(x:ICar,y:number):ICar{
}
// 注解数组包对象
let arr:Array<ICar>=[
  {name:"1",age:"2"},
  {
  name:"12",age:"22"
}
]
// 泛型函数
  // function run(x:string,y:number|string,z:boolean):string{
  //     return "12321"
  // }
  // 泛型变量 经常使用字母T,U,V
  function run<T,U>(x:T,y:U,z:string):T{
      console.log("泛型函数调用了")
      
  }
  run<string,number>("盛世嫡妃",434,"撒旦法")
  
  run<boolean,Array<number>>(true,[1,2,3],"234")
// 泛型接口
 interface Iphone<T,U>{
   name:T,
   color:U,
   call(h:T):T
 }
 let myphone:Iphone<string,number>={
    name:"华为x5",
    color:88,
    call(h:string):string{
      console.log("打电话")
    }
 }
myphone.call()
let myph:Iphone<Array<any>, boolean>  ={
  name:[1,23,true],
  color:false,
  call(h:Array<any>):Array<any>{
    console.log("打电话")
  }
}
// 泛型类
class Person<T,U,V>{
    name:T;
    age:U;
  constructor(name:T,age:U){
       this.name=name;
       this.age=age;
  }
  public eat(food:V):V{
    console.log("吃了什么食物"+food)
    return food
  }
  protected kl(kk:T){

  }
  private run():T {
    
  }
}
let xiaowang=new Person<string,number,boolean>("王德发",33);
xiaowang.eat(true)


let xiaoli=new Person<Array<string>,string,number>(["李小龙","李连杰"],"324")


// 如vue3的ref的泛型使用 ref的泛型使用
let kk=ref<number>(88)
console.log(kk.value)
 
// ts 新增类型 any void 
const sym1:symbol = Symbol(); //唯一值
// 1 unknown未知类型的值，需要进行类型检查或类型断言才能使用
//1.类型断言解决
let jf:unknown;
function divide(param: unknown) {
  return (param as number) / 2;
}
// 2.never 永不存在的值的类型
// 如函数不会执行到返回值  用never
function fn(msg: string): never { 
  throw new Error(msg)
  return "sdfdf"
}
// 3.元组类型
// 元组类型就是在定义数组的时候，类型和数据的个数一开始就已经限定好了。
let arr1:[ string ,number,boolean,number,string] = [ "123" , 520, true ,34,"3245"]

//4. enum枚举允许开发者定义一组命名的常量。使用枚举可以使其更容易记录意图，或创建一组不同的情况。TypeScript提供了基于数字和字符串的枚举。
enum Direction {
    Up=3, // 3
    Down,// 4
    Left,// 5
    Right// 6
}
console.log('枚举',Direction.Left)
enum klist {
    Up="你好", 
    Down="哈哈",
    Left="123",
    Right="内存"
}
console.log("------",klist.Right)

//ts是什么，有哪些新特性 



</script>
